package main

import (
	"fmt"
	"sort"
)

// 第一题：实现对圆形、三角形、长方形求面积

// 定义一个求各种图形面积的接口
type Areaer interface {
	Area() float64
}

// 圆形
type Circular struct {
	r float64
}

// 三角形
type Triangle struct {
	bottom float64
	height float64
}

// 长方形
type Rectangle struct {
	long  float64
	width float64
}

// 定义一个圆形的构造函数
func NewCircular(r float64) *Circular {
	return &Circular{r}
}

// 定义一个三角形的构造函数
func NewTriangle(bottom, height float64) *Triangle {
	return &Triangle{bottom, height}
}

// 定义一个长方形的构造函数
func NewRectangle(long, width float64) *Rectangle {
	return &Rectangle{long, width}
}

// 定义一个求圆形面积的方法并且实现了areaer接口
func (c *Circular) Area() float64 {
	// return math.Pi * c.r * c.r
	return float64(3.14) * c.r * c.r
}

// 定义一个求三角形面积的方法并且实现了areaer接口
func (t *Triangle) Area() float64 {
	return t.bottom * t.height / 2
}

// 定义一个求长方形面积的方法并且实现了areaer接口
func (r *Rectangle) Area() float64 {
	return r.long * r.width
}

// 第三题  分析斐波那契数列递推公式版本的问题，试着为该函数提供一个Cache，使其计算效率提升
// 定义一个map来作为缓存
var Cache = make(map[int]int)

// 定义一个fibonacci函数
func fibonacci(n int) int {
	if value, ok := Cache[n]; ok {
		return value
	}
	if n <= 1 && n >= 0 {
		return n
	}
	Cache[n] = fibonacci(n-1) + fibonacci(n-2)
	return Cache[n]
}

func main() {
	AreaArray := []float64{}
	// 圆形
	c := NewCircular(2)
	fmt.Println(c.Area())
	// 三角形
	t := NewTriangle(3, 4)
	fmt.Println(t.Area())
	// 长方形
	r := NewRectangle(3, 4)
	fmt.Println(r.Area())
	// 第二题：利用第1题，构造3个以上图形，至少圆形、三角形、矩形各一个，对上题的图案按照面积降序排列
	AreaArray = append(AreaArray, c.Area(), t.Area(), r.Area())
	sort.Slice(AreaArray, func(i, j int) bool {
		return !(AreaArray[i] < AreaArray[j])
	})
	fmt.Println(AreaArray)
	// 第三题测试 测试后发现，使用缓存后，计算效率提升
	m := 100
	fmt.Println(fibonacci(m))
}
